﻿using JIESHINet.Common;
using JIESHINet.Common.Const;
using JIESHINet.Common.DB;
using JIESHINet.Common.Option;
using JIESHINet.Model;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using SqlSugar.Extensions;
using System.Reflection;

namespace JIESHINet.Extension.SQLSugar
{
    /// <summary>
    /// SqlSugar 启动服务
    /// </summary>
    public static class SqlsugarSetup
    {
        public static void AddSqlsugarSetup(this IServiceCollection services)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));

            // 默认添加主数据库连接
            if (!string.IsNullOrEmpty(AppSettings.app("MainDB")))
            {
                MainDb.CurrentDbConnId = AppSettings.app("MainDB");
            }

            //把自定义的List<MutiDBOperate>对象转为List<ConnectionConfig>对象
            BaseDBConfig.MutiConnectionString.allDbs.ForEach(m =>
            {
                var config = new ConnectionConfig()
                {
                    ConfigId = m.ConnId.ObjToString().ToLower(),
                    ConnectionString = m.Connection,
                    DbType = (DbType)m.DbType,
                    IsAutoCloseConnection = true,
                    MoreSettings = new ConnMoreSettings()
                    {
                        IsAutoRemoveDataCache = true,
                        SqlServerCodeFirstNvarchar = true,
                    },
                    InitKeyType = InitKeyType.Attribute
                };
                if (SqlSugarConst.LogConfigId.ToLower().Equals(m.ConnId.ToLower()))
                {
                    BaseDBConfig.LogConfig = config;
                }
                else
                {
                    BaseDBConfig.ValidConfig.Add(config);
                }

                BaseDBConfig.AllConfigs.Add(config);
            });

            if (BaseDBConfig.LogConfig is null)
            {
                throw new ApplicationException("未配置Log库连接");
            }

            // 注册ISqlSugarClient接口 实现SqlSugarScope实例
            // 参考：https://www.donet5.com/Home/Doc?typeId=1181。因此SqlSugarScope是线程安全，没有用Transient瞬态可使用单例注入 
            
            services.AddSingleton<ISqlSugarClient>(o =>
            {
                var db = new SqlSugarScope(BaseDBConfig.AllConfigs);
                #region CodeFirst
                var basepath = AppContext.BaseDirectory;
                var servicesDllfile = Path.Combine(basepath, "JIESHINet.Model.dll");
                var assemblysService = Assembly.LoadFrom(servicesDllfile);
                // 检查服务集合是否为 null，如果为 null 则抛出参数异常
                if (services == null) throw new ArgumentNullException(nameof(assemblysService));
                // 遍历JIESHINet.Commonc程序集中所有非ConfigurableOptions且实现了 IConfigurableOptions 接口的类型
                foreach (var optionType in typeof(RootEntityTkey<long>).Assembly.GetTypes().Where(s =>
                             !s.IsInterface && typeof(RootEntityTkey<long>).IsAssignableFrom(s)))
                {
                    if (!db.DbMaintenance.IsAnyTable(optionType.Name))
                    {
                        // 表不存在，执行创建表操作
                        db.CodeFirst.InitTables(optionType);
                        Console.WriteLine($"数据库不存在{optionType.Name}表，执行CodeFirst生成");
                    }
                }
                
                #endregion
                return db;
            });

            
        }
    }
}